package com.myebills.ebpsfrontend.cust.controller;

import java.io.Serializable;
import java.net.InetAddress;
import java.net.UnknownHostException;
import com.ibm.logging.ConsoleHandler;
import com.ibm.logging.IRecordType;
import com.ibm.logging.MessageLogger;
import com.ibm.logging.TraceFormatter;
import com.ibm.logging.TraceLogger;

/**
 * Maintains a logger and tracer for a single HTTP request/response thread.
 */
public class EbppxLogger implements Serializable {

    /**
     * The attribute name used to store an instance of this class
     * in the request scope for access by Java Server Pages.
     */
    public static final String REQUEST_ATTRIBUTE_NAME = "EbppxLogger";

    /**
     * The following items are "singleton" handlers shared by all
     * instances of the EbppxLogger component.
     * All accesses to these variables MUST be synchronized.
     */
    static private com.ibm.logging.Handler messageHandler;
    static private com.ibm.logging.Handler traceHandler;

    transient private com.ibm.logging.ILogger msgLogger;
    transient private com.ibm.logging.ILogger trcLogger;

    /**
     * No-argument constructor intended only for use by Java Beans
     * serialization mechanism.
     * <b><em>Note:</em></b>
     * Do <em>not</em> use this constructor for explicit creation of
     * instances of this class.
     * Instead, use the constructor that takes parameters.
     */
    private EbppxLogger() {
        // Default constructor
    }

    /**
     * Construct thread-specific logging instance.
     * <p>
     * Depends on values of servlet initialization parameters "messageLogPath", "messageLogDescription",
     * "traceLogPath", "traceLogDescription", "organization", "product", and "component".
     * If servlet init param "messageLogging" is "true", "messageLogPath" must also be defined.
     * If servlet init param "traceLogging" is "true", "traceLogPath" must also be defined.
     * All other parameters are optional.
     */
    public EbppxLogger(EbppxServlet servlet) {
        msgLogger = new MessageLogger();
        trcLogger = new TraceLogger();

        msgLogger.setLogging(
                EbppxUtil.boolFromString(
                    servlet.getInitParameter("messageLogging", null)
                    )
                );
        trcLogger.setLogging(
                EbppxUtil.boolFromString(
                    servlet.getInitParameter("traceLogging", null)
                    )
                );

        msgLogger.setOrganization(servlet.getInitParameter("organization", ""));
        trcLogger.setOrganization(servlet.getInitParameter("organization", ""));

        msgLogger.setProduct(servlet.getInitParameter("product", ""));
        trcLogger.setProduct(servlet.getInitParameter("product", ""));

        msgLogger.setComponent(servlet.getInitParameter("component", ""));
        trcLogger.setComponent(servlet.getInitParameter("component", ""));

        String client;
        try {
            client = InetAddress.getLocalHost().getHostName();
        } catch (UnknownHostException e) {
            client = "localhost";
        }

        msgLogger.setServer(client);
        trcLogger.setServer(client);

        msgLogger.setClient("");
        trcLogger.setClient("");

        msgLogger.addHandler(getMessageHandler());
        trcLogger.addHandler(getTraceHandler());

        trcLogger.removeAllFilters();
    }

    /**
     * Call when a servlet instance is ready to be destroyed.
     */
    public static void quitLogging(EbppxServlet servlet) {
        synchronized (EbppxLogger.class) {
            if (messageHandler.isLogging()) {
                messageHandler.stop();
            }

            if (traceHandler.isLogging()) {
                traceHandler.stop();
            }
        }
    }

    /**
     * Return a reference to a logger for providing
     * message logging services.
     * The purpose of message logging is to provide information
     * to the users of an application.
     * Contrast this with tracing,
     * which is intended for software developers and service teams.
     * As a general guideline,
     * a message should be logged only if the information it contains
     * is of value to the user.
     *
     * @return an instance of <code>com.ibm.logging.MessageLogger</code>
     */
    public com.ibm.logging.ILogger getMessageLogger() {
        return msgLogger;
    }

    /**
     * Return a reference to a logger for providing tracing services.
     * The purpose of tracing is to provide sufficient information
     * to a developer or service team to diagnose a problem remotely;
     * for example, when the application is in production.
     * Normally an application will run with tracing turned off.
     * When a problem occurs,
     * it can be turned on to gather the data needed
     * to understand the problem.
     *
     * @return an instance of <code>com.ibm.logging.TraceLogger</code>
     */
    public com.ibm.logging.ILogger getTraceLogger() {
        return trcLogger;
    }

    /**
     * Thread-safe lazy-initialization accessor for shared msgLog.
     */
    private com.ibm.logging.Handler getMessageHandler() {
        synchronized (EbppxLogger.class) {
            if (messageHandler == null) {
                messageHandler = new com.ibm.logging.FileHandler("messages.log");
            }
            return messageHandler;
        }
    }

    /**
     * Thread-safe lazy-initialization accessor for shared msgLog.
     */
    private com.ibm.logging.Handler getTraceHandler() {
        synchronized (EbppxLogger.class) {
            if (traceHandler == null) {
                traceHandler = new ConsoleHandler();
                traceHandler.addFormatter(new TraceFormatter());
            }
            return traceHandler;
        }
    }
}